<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Peaks.js Demo Page</title>
    <link rel="stylesheet" type="text/css" href="style.css">
  </head>
  <body>
    <div id="titles">
      <h1>Peaks.js</h1>
      <p>
        Peaks.js is a JavaScript library that allows you to display and
        interact with audio waveforms in the browser.
      </p>

      <h2>Demo pages</h2>
      <p>
        The following pages demonstrate various configuration options:
      </p>
      <p>
        <a href="/index.html">Precomputed Waveform Data</a> |
        <a href="/webaudio.html">Web Audio API</a> |
        <a href="/zoomable-waveform.html">Single Zoomable Waveform</a> |
        <a href="/overview-waveform.html">Single Fixed Waveform</a> |
        <a href="/cue-events.html">Cue Events</a> |
        <a href="/set-source.html">Changing the Media URL</a> |
        <a href="/multi-channel.html">Multi-Channel Waveform</a> |
        <a href="/custom-markers">Custom Point and Segment Markers</a> |
        Overlay Segments |
        <a href="/external-player.html">External Audio Player</a> |
        <a href="/scrollbar.html">Scrollbar</a>
      </p>
      <h2>Demo: Overlay Segments</h2>
      <p>
        This demo shows how to configure Peaks.js to use overlay segments
        and the available options to customize segment appearance.
      </p>
    </div>

    <div class="waveform-container">
      <div id="zoomview-container"></div>
    </div>
    <div class="waveform-container">
      <div id="overview-container"></div>
    </div>

    <div id="demo-controls">
      <audio id="audio" controls="controls">
        <source src="/TOL_6min_720p_download.mp3" type="audio/mpeg">
        <source src="/TOL_6min_720p_download.ogg" type='audio/ogg; codecs="vorbis"'>
        Your browser does not support the audio element.
      </audio>

      <div id="controls">
        <div>
          <button data-action="zoom-in">Zoom in</button>
          <button data-action="zoom-out">Zoom out</button>
          <input type="text" id="seek-time" value="0.0">
          <button data-action="seek">Seek</button>
          <label for="amplitude-scale">Amplitude scale</label>
          <input type="range" id="amplitude-scale" min="0" max="10" step="1">
        </div>
        <div>
          <label for="mousewheel-mode">Mousewheel mode:</label>
          <select id="mousewheel-mode">
            <option value="none">None</option>
            <option value="scroll">Scroll</option>
          </select>
          <input type="checkbox" id="auto-scroll" checked>
          <label for="auto-scroll">Auto-scroll</label>
          <input type="checkbox" id="playhead-time" checked>
          <label for="playhead-time">Show playhead time</label>
        </div>
        <div>
          <button data-action="add-segment">Add Segment</button>
          <button data-action="add-point">Add Point</button>
          <button data-action="log-data">Log segments/points</button>
        </div>
        <div>
          <button data-action="resize">Resize</button>
          <button data-action="toggle-zoomview">Show/hide zoomable waveform</button>
          <button data-action="toggle-overview">Show/hide overview waveform</button>
          <button data-action="destroy">Destroy</button>
        </div>
        <div>
          <input type="checkbox" id="enable-seek" checked>
          <label for="enable-seek">Enable click to seek</label>
          <label for="waveform-drag-mode">Waveform drag mode:</label>
          <select id="waveform-drag-mode">
            <option value="scroll">Scroll</option>
            <option value="insert-segment">Insert segment</option>
          </select>
        </div>
        <div>
          <input type="checkbox" id="enable-segment-dragging">
          <label for="enable-segment-dragging">Enable segment dragging</label>
          <label for="segment-drag-mode">Segment drag mode:</label>
          <select id="segment-drag-mode">
            <option value="overlap">Overlap</option>
            <option value="no-overlap">No overlap</option>
            <option value="compress">Compress</option>
          </select>
        </div>
      </div>
    </div>

    <div class="log">
      <div id="segments" class="hide">
        <h2>Segments</h2>
        <table>
          <thead>
            <tr>
              <th>ID</th>
              <th>Label</th>
              <th>Start time</th>
              <th>End time</th>
              <th></th>
            </tr>
          </thead>
          <tbody>
          </tbody>
        </table>
      </div>

      <div id="points" class="hide">
        <h2>Points</h2>
        <table>
          <thead>
            <tr>
              <th>ID</th>
              <th>Label</th>
              <th>Time</th>
            </tr>
          </thead>
          <tbody>
          </tbody>
        </table>
      </div>
    </div>

    <script src="/peaks.js"></script>
    <script>
      (function(Peaks) {
        var renderSegments = function(peaks) {
          var segmentsContainer = document.getElementById('segments');
          var segments = peaks.segments.getSegments();
          var html = '';

          for (var i = 0; i < segments.length; i++) {
            var segment = segments[i];

            var row = '<tr>' +
              '<td>' + segment.id + '</td>' +
              '<td><input data-action="update-segment-label" type="text" value="' + segment.labelText + '" data-id="' + segment.id + '"/></td>' +
              '<td><input data-action="update-segment-start-time" type="number" value="' + segment.startTime + '" data-id="' + segment.id + '"/></td>' +
              '<td><input data-action="update-segment-end-time" type="number" value="' + segment.endTime + '" data-id="' + segment.id + '"/></td>' +
              '<td>' + '<a href="#' + segment.id + '" data-action="play-segment" data-id="' + segment.id + '">Play</a>' + '</td>' +
              '<td>' + '<a href="#' + segment.id + '" data-action="loop-segment" data-id="' + segment.id + '">Loop</a>' + '</td>' +
              '<td>' + '<a href="#' + segment.id + '" data-action="remove-segment" data-id="' + segment.id + '">Remove</a>' + '</td>' +
              '</tr>';

            html += row;
          }

          segmentsContainer.querySelector('tbody').innerHTML = html;

          if (html.length) {
            segmentsContainer.classList.remove('hide');
          }

          document.querySelectorAll('input[data-action="update-segment-start-time"]').forEach(function(inputElement) {
            inputElement.addEventListener('input', function(event) {
              var element = event.target;
              var id = element.getAttribute('data-id');
              var segment = peaks.segments.getSegment(id);

              if (segment) {
                var startTime = parseFloat(element.value);

                if (startTime < 0) {
                  startTime = 0;
                  element.value = 0;
                }

                if (startTime >= segment.endTime) {
                  startTime = segment.endTime - 0.1;
                  element.value = startTime;
                }

                segment.update({ startTime: startTime });
              }
            });
          });

          document.querySelectorAll('input[data-action="update-segment-end-time"]').forEach(function(inputElement) {
            inputElement.addEventListener('input', function(event) {
              var element = event.target;
              var id = element.getAttribute('data-id');
              var segment = peaks.segments.getSegment(id);

              if (segment) {
                var endTime = parseFloat(element.value);

                if (endTime < 0) {
                  endTime = 0;
                  element.value = 0;
                }

                if (endTime <= segment.startTime) {
                  endTime = segment.startTime + 0.1;
                  element.value = endTime;
                }

                segment.update({ endTime: endTime });
              }
            });
          });

          document.querySelectorAll('input[data-action="update-segment-label"]').forEach(function(inputElement) {
            inputElement.addEventListener('input', function(event) {
              var element = event.target;
              var id = element.getAttribute('data-id');
              var segment = peaks.segments.getSegment(id);
              var labelText = element.labelText;

              if (segment) {
                segment.update({ labelText: labelText });
              }
            });
          });
        };

        var renderPoints = function(peaks) {
          var pointsContainer = document.getElementById('points');
          var points = peaks.points.getPoints();
          var html = '';

          for (var i = 0; i < points.length; i++) {
            var point = points[i];

            var row = '<tr>' +
              '<td>' + point.id + '</td>' +
              '<td><input data-action="update-point-label" type="text" value="' + point.labelText + '" data-id="' + point.id + '"/></td>' +
              '<td><input data-action="update-point-time" type="number" value="' + point.time + '" data-id="' + point.id + '"/></td>' +
              '<td>' + '<a href="#' + point.id + '" data-action="remove-point" data-id="' + point.id + '">Remove</a>' + '</td>' +
              '</tr>';

            html += row;
          }

          pointsContainer.querySelector('tbody').innerHTML = html;

          if (html.length) {
            pointsContainer.classList.remove('hide');
          }

          document.querySelectorAll('input[data-action="update-point-time"]').forEach(function(inputElement) {
            inputElement.addEventListener('input', function(event) {
              var element = event.target;
              var id = element.getAttribute('data-id');
              var point = peaks.points.getPoint(id);

              if (point) {
                var time = parseFloat(element.value);

                if (time < 0) {
                  time = 0;
                  element.value = 0;
                }

                point.update({ time: time });
              }
            });
          });

          document.querySelectorAll('input[data-action="update-point-label"]').forEach(function(inputElement) {
            inputElement.addEventListener('input', function(event) {
              var element = event.target;
              var id = element.getAttribute('data-id');
              var point = peaks.points.getPoint(id);
              var labelText = element.labelText;

              if (point) {
                point.update({ labelText: labelText });
              }
            });
          });
        };

        var options = {
          zoomview: {
            container: document.getElementById('zoomview-container'),
            playheadClickTolerance: 3
          },
          overview: {
            container: document.getElementById('overview-container')
          },
          mediaElement: document.getElementById('audio'),
          dataUri: {
            arraybuffer: '/TOL_6min_720p_download.dat',
            json: '/TOL_6min_720p_download.json'
          },
          keyboard: true,
          pointMarkerColor: '#006eb0',
          showPlayheadTime: true,
          waveformCache: true,
          zoomLevels: [512, 1024, 2048, 4096],
          segmentOptions: {
            markers:                   false,
            overlay:                   true,
            waveformColor:             '#ff851b',
            overlayColor:              '#ff0000',
            overlayOpacity:            0.3,
            overlayBorderColor:        '#ff0000',
            overlayBorderWidth:        2,
            overlayCornerRadius:       5,
            overlayOffset:             40,
            overlayLabelAlign:         'left',
            overlayLabelVerticalAlign: 'top',
            overlayLabelPadding:       8,
            overlayLabelColor:         '#000000',
            overlayFontFamily:         'sans-serif',
            overlayFontSize:           14,
            overlayFontStyle:          'normal'
          },
          createSegmentLabel: function() { return null; },
        };

        Peaks.init(options, function(err, peaksInstance) {
          if (err) {
            console.error(err.message);
            return;
          }

          console.log("Peaks instance ready");

          peaksInstance.views.getView('zoomview').setMinSegmentDragWidth(50);

          document.querySelector('[data-action="zoom-in"]').addEventListener('click', function() {
            peaksInstance.zoom.zoomIn();
          });

          document.querySelector('[data-action="zoom-out"]').addEventListener('click', function() {
            peaksInstance.zoom.zoomOut();
          });

          var segmentCounter = 1;

          document.querySelector('button[data-action="add-segment"]').addEventListener('click', function() {
            peaksInstance.segments.add({
              startTime: peaksInstance.player.getCurrentTime(),
              endTime: peaksInstance.player.getCurrentTime() + 2,
              labelText: 'Test segment ' + segmentCounter++,
              editable: true
            });
          });

          document.querySelector('button[data-action="add-point"]').addEventListener('click', function() {
            peaksInstance.points.add({
              time: peaksInstance.player.getCurrentTime(),
              labelText: 'Test point',
              editable: true
            });
          });

          document.querySelector('button[data-action="log-data"]').addEventListener('click', function(event) {
            renderSegments(peaksInstance);
            renderPoints(peaksInstance);
          });

          document.querySelector('button[data-action="seek"]').addEventListener('click', function(event) {
            var time = document.getElementById('seek-time').value;
            var seconds = parseFloat(time);

            if (!Number.isNaN(seconds)) {
              peaksInstance.player.seek(seconds);
            }
          });

          document.getElementById('mousewheel-mode').addEventListener('change', function(event) {
            var mode = event.target.value;
            var view = peaksInstance.views.getView('zoomview');

            view.setWheelMode(mode);
          });

          document.querySelector('button[data-action="destroy"]').addEventListener('click', function(event) {
            peaksInstance.destroy();
          });

          document.getElementById('auto-scroll').addEventListener('change', function(event) {
            var view = peaksInstance.views.getView('zoomview');
            view.enableAutoScroll(event.target.checked);
          });

          document.getElementById('playhead-time').addEventListener('change', function(event) {
            var view = peaksInstance.views.getView('zoomview');
            view.showPlayheadTime(event.target.checked);
          });

          document.getElementById('enable-seek').addEventListener('change', function(event) {
            var overview = peaksInstance.views.getView('overview');
            var zoomview = peaksInstance.views.getView('zoomview');

            zoomview.enableSeek(event.target.checked);
            overview.enableSeek(event.target.checked);
          });

          document.getElementById('waveform-drag-mode').addEventListener('change', function(event) {
            var view = peaksInstance.views.getView('zoomview');

            view.setWaveformDragMode(event.target.value);
          });

          document.getElementById('enable-segment-dragging').addEventListener('change', function(event) {
            var zoomview = peaksInstance.views.getView('zoomview');

            zoomview.enableSegmentDragging(event.target.checked);
          });

          document.getElementById('segment-drag-mode').addEventListener('change', function(event) {
            var view = peaksInstance.views.getView('zoomview');

            view.setSegmentDragMode(event.target.value);
          });

          document.querySelector('body').addEventListener('click', function(event) {
            var element = event.target;
            var action  = element.getAttribute('data-action');
            var id      = element.getAttribute('data-id');

            if (action === 'play-segment') {
              var segment = peaksInstance.segments.getSegment(id);
              peaksInstance.player.playSegment(segment);
            }
            else if (action === 'loop-segment') {
              var segment = peaksInstance.segments.getSegment(id);
              peaksInstance.player.playSegment(segment, true);
            }
            else if (action === 'remove-point') {
              peaksInstance.points.removeById(id);
            }
            else if (action === 'remove-segment') {
              peaksInstance.segments.removeById(id);
            }
          });

          var amplitudeScales = {
            "0": 0.0,
            "1": 0.1,
            "2": 0.25,
            "3": 0.5,
            "4": 0.75,
            "5": 1.0,
            "6": 1.5,
            "7": 2.0,
            "8": 3.0,
            "9": 4.0,
            "10": 5.0
          };

          document.getElementById('amplitude-scale').addEventListener('input', function(event) {
            var scale = amplitudeScales[event.target.value];

            peaksInstance.views.getView('zoomview').setAmplitudeScale(scale);
            peaksInstance.views.getView('overview').setAmplitudeScale(scale);
          });

          document.querySelector('button[data-action="resize"]').addEventListener('click', function(event) {
            const zoomviewContainer = document.getElementById('zoomview-container');
            const overviewContainer = document.getElementById('overview-container');

            zoomviewContainer.style.height = zoomviewContainer.offsetHeight === 200 ? "300px" : "200px";
            overviewContainer.style.height = overviewContainer.offsetHeight === 200 ? "85px"  : "200px";

            const zoomview = peaksInstance.views.getView('zoomview');

            if (zoomview) {
              zoomview.fitToContainer();
            }

            const overview = peaksInstance.views.getView('overview');

            if (overview) {
              overview.fitToContainer();
            }
          });

          document.querySelector('button[data-action="toggle-zoomview"]').addEventListener('click', function(event) {
            var container = document.getElementById('zoomview-container');
            var zoomview = peaksInstance.views.getView('zoomview');

            if (zoomview) {
              peaksInstance.views.destroyZoomview();
              container.style.display = 'none';
            }
            else {
              container.style.display = 'block';
              peaksInstance.views.createZoomview(container);
            }
          });

          document.querySelector('button[data-action="toggle-overview"]').addEventListener('click', function(event) {
            var container = document.getElementById('overview-container');
            var overview = peaksInstance.views.getView('overview');

            if (overview) {
              peaksInstance.views.destroyOverview();
              container.style.display = 'none';
            }
            else {
              container.style.display = 'block';
              peaksInstance.views.createOverview(container);
            }
          });

          // Point events

          peaksInstance.on('points.add', function(event) {
            console.log('points.add:', event);
          });

          peaksInstance.on('points.mouseenter', function(event) {
            console.log('points.mouseenter:', event);
          });

          peaksInstance.on('points.mouseleave', function(event) {
            console.log('points.mouseleave:', event);
          });

          peaksInstance.on('points.click', function(event) {
            console.log('points.click:', event);
          });

          peaksInstance.on('points.dblclick', function(event) {
            console.log('points.dblclick:', event);
          });

          peaksInstance.on('points.contextmenu', function(event) {
            event.evt.preventDefault();

            console.log('points.contextmenu:', event);
          });

          peaksInstance.on('points.dragstart', function(event) {
            console.log('points.dragstart:', event);
          });

          peaksInstance.on('points.dragmove', function(event) {
            console.log('points.dragmove:', event);
          });

          peaksInstance.on('points.dragend', function(event) {
            console.log('points.dragend:', event);
          });

          // Segment events

          peaksInstance.on('segments.add', function(event) {
            console.log('segments.add:', event);
          });

          peaksInstance.on('segments.insert', function(event) {
            console.log('segments.insert:', event);
          });

          peaksInstance.on('segments.dragstart', function(event) {
            console.log('segments.dragstart:', event);
          });

          peaksInstance.on('segments.dragend', function(event) {
            console.log('segments.dragend:', event);
          });

          peaksInstance.on('segments.dragged', function(event) {
            console.log('segments.dragged:', event);
          });

          peaksInstance.on('segments.mouseenter', function(event) {
            console.log('segments.mouseenter:', event);
          });

          peaksInstance.on('segments.mouseleave', function(event) {
            console.log('segments.mouseleave:', event);
          });

          peaksInstance.on('segments.mousedown', function(event) {
            console.log('segments.mousedown:', event);
          });

          peaksInstance.on('segments.mouseup', function(event) {
            console.log('segments.mouseup:', event);
          });

          peaksInstance.on('segments.click', function(event) {
            console.log('segments.click:', event);
          });

          peaksInstance.on('segments.dblclick', function(event) {
            console.log('segments.dblclick:', event);
          });

          peaksInstance.on('segments.contextmenu', function(event) {
            event.evt.preventDefault();

            console.log('segments.contextmenu:', event);
          });

          // Zoomview waveform events

          peaksInstance.on('zoomview.click', function(event) {
            console.log('zoomview.click:', event);
          });

          peaksInstance.on('zoomview.dblclick', function(event) {
            console.log('zoomview.dblclick:', event);
          });

          peaksInstance.on('zoomview.contextmenu', function(event) {
            event.evt.preventDefault();

            console.log('zoomview.contextmenu:', event);
          });

          peaksInstance.on('zoomview.update', function(event) {
            console.log('zoomview.update:', event);
          });

          // Overview waveform events

          peaksInstance.on('overview.click', function(event) {
            console.log('overview.click:', event);
          });

          peaksInstance.on('overview.dblclick', function(event) {
            console.log('overview.dblclick:', event);
          });

          peaksInstance.on('overview.contextmenu', function(event) {
            event.evt.preventDefault();

            console.log('overview.contextmenu:', event);
          });

          // Player events

          peaksInstance.on('player.seeked', function(time) {
            console.log('player.seeked:', time);
          });

          peaksInstance.on('player.playing', function(time) {
            console.log('player.playing:', time);
          });

          peaksInstance.on('player.pause', function(time) {
            console.log('player.pause:', time);
          });

          peaksInstance.on('player.ended', function() {
            console.log('player.ended');
          });
        });
      })(peaks);
    </script>
  </body>
</html>
